/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "dac.h"
#include "usart.h"
#include "gpio.h"
#include "fsmc.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "lcd.h"
#include "stdio.h"
#include "ad9959.h"
#include "multipath.h"
#include "pe43702.h"
#include "util.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
uint16_t mod_signal_freq_MHz = 2, carrier_wave_freq_MHz = 30, Ma_percent = 0;
uint16_t multipath_time_delay_ns = 0, multipath_amp_attenuation_dB = 0;
uint16_t multipath_phase_delay_degree = 0;
uint16_t carrier_wave_amp_effective_mV = 500;
GPIO_PinState	key_up_pin_state_new = GPIO_PIN_RESET, key_up_pin_state_old = GPIO_PIN_RESET;
GPIO_PinState	key2_pin_state_new = GPIO_PIN_SET, key2_pin_state_old = GPIO_PIN_SET;
GPIO_PinState	key1_pin_state_new = GPIO_PIN_SET, key1_pin_state_old = GPIO_PIN_SET;
GPIO_PinState	key0_pin_state_new = GPIO_PIN_SET, key0_pin_state_old = GPIO_PIN_SET;
extern char LCDBuffer1[], LCDBuffer2[], LCDBuffer3[], LCDBuffer4[], LCDBuffer5[], LCDBuffer6[];
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
	uint16_t function = 1;
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_FSMC_Init();
  MX_USART1_UART_Init();
  MX_DAC_Init();
  /* USER CODE BEGIN 2 */
	HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, 0);
 	LCD_Init();           			//初始化LCD FSMC接口
	LCD_Clear(DARKBLUE);
	ad9959_init();
	
	ad9959_write_amplitude(AD9959_CHANNEL_0, 1023);
	ad9959_write_amplitude(AD9959_CHANNEL_2, 1023);
	ad9959_change_mod_signal_amp(Ma_percent);
	
	ad9959_change_carrier_wave_freq(carrier_wave_freq_MHz);
	ad9959_change_mod_signal_freq(mod_signal_freq_MHz);
	
	set_pe43702_attenuation_dB(multipath_amp_attenuation_dB);
	ad9959_change_multipath_phase(multipath_time_delay_ns, multipath_phase_delay_degree, mod_signal_freq_MHz, carrier_wave_freq_MHz);
	POINT_COLOR=YELLOW;
	LCD_ShowString(40,50,400,24,24,"Welcome to National Undergraduate");
	LCD_ShowString(90,80,400,24,24,"Electronic Design Contest");
	POINT_COLOR=GRAY;
	LCD_ShowString(30,150,400,24,24,"Carrier Wave");
	LCD_ShowString(30,400,400,24,24,"Multipath Signal");
	ad603_change_carrier_wave_amp(carrier_wave_amp_effective_mV, carrier_wave_freq_MHz, Ma_percent);
//	set_DAC1_value(1297);//打点专用，平常保持注释
	set_DAC2_value(580);//调制信号直流偏置，勿动，勿注释
	HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_SET);
	HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_RESET);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		sprintf(LCDBuffer1,"Freq: %d MHz", carrier_wave_freq_MHz);
		if(function == 1) POINT_COLOR=CYAN;
		LCD_ShowString(30,200,400,24,24,LCDBuffer1);
		if(function == 1) POINT_COLOR=WHITE;
		
		sprintf(LCDBuffer2,"Effective Voltage: %d mV  ", carrier_wave_amp_effective_mV);
		if(function == 2) POINT_COLOR=CYAN;
		LCD_ShowString(30,250,400,24,24,LCDBuffer2);
		if(function == 2) POINT_COLOR=WHITE;
		
		sprintf(LCDBuffer3,"AM Modulation Depth: %d %% ", Ma_percent);
		if(function == 3) POINT_COLOR=CYAN;
		LCD_ShowString(30,300,400,24,24,LCDBuffer3);
		if(function == 3) POINT_COLOR=WHITE;
		
		sprintf(LCDBuffer4,"Time Delay: %d ns  ", multipath_time_delay_ns);
		if(function == 4) POINT_COLOR=CYAN;
		LCD_ShowString(30,450,400,24,24,LCDBuffer4);
		if(function == 4) POINT_COLOR=WHITE;
		
		sprintf(LCDBuffer5,"Amp Attenuation: %d dB ", multipath_amp_attenuation_dB);
		if(function == 5) POINT_COLOR=CYAN;
		LCD_ShowString(30,500,400,24,24,LCDBuffer5);
		if(function == 5) POINT_COLOR=WHITE;
		
		sprintf(LCDBuffer6,"Phase Delay: %d degree  ", multipath_phase_delay_degree);
		if(function == 6) POINT_COLOR=CYAN;
		LCD_ShowString(30,550,400,24,24,LCDBuffer6);
		if(function == 6) POINT_COLOR=WHITE;
// 		LCD_ShowString(30,110,200,16,16,lcd_id);		//显示LCD ID	      					 
//		LCD_ShowString(30,130,200,12,12,"2024/7/29");	      					 
//		HAL_GPIO_TogglePin(LCD_BL_GPIO_Port, LCD_BL_Pin);//LED0=!LED0;
		key_up_pin_state_new = HAL_GPIO_ReadPin(KEY_UP_GPIO_Port,KEY_UP_Pin);
		if ((key_up_pin_state_new == GPIO_PIN_SET) && (key_up_pin_state_old == GPIO_PIN_RESET)){
			HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_RESET);
			function--;
			if(function<1) function = 6;
		}
		key_up_pin_state_old = key_up_pin_state_new;
		
		key2_pin_state_new = HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin);
		if ((key2_pin_state_new == GPIO_PIN_RESET) && (key2_pin_state_old == GPIO_PIN_SET)){
			HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_RESET);
			switch(function){
				case 1:{
					carrier_wave_freq_MHz--;
					if(carrier_wave_freq_MHz < 30) carrier_wave_freq_MHz = 30;
					ad9959_change_carrier_wave_freq(carrier_wave_freq_MHz);
					ad603_change_carrier_wave_amp(carrier_wave_amp_effective_mV, carrier_wave_freq_MHz, Ma_percent);
					ad9959_change_multipath_phase(multipath_time_delay_ns, multipath_phase_delay_degree, mod_signal_freq_MHz, carrier_wave_freq_MHz);
					break;
				}
				case 2:{
					if(carrier_wave_amp_effective_mV < 150) carrier_wave_amp_effective_mV = 100;
					else carrier_wave_amp_effective_mV-=100;
					ad603_change_carrier_wave_amp(carrier_wave_amp_effective_mV, carrier_wave_freq_MHz, Ma_percent);
					break;
				}
				case 3:{
					if(Ma_percent < 1) Ma_percent = 90;
					else Ma_percent-=5;
					ad9959_change_mod_signal_amp(Ma_percent);
					ad603_change_carrier_wave_amp(carrier_wave_amp_effective_mV, carrier_wave_freq_MHz, Ma_percent);
					break;
				}
				case 4:{
					if(multipath_time_delay_ns < 1) multipath_time_delay_ns = 200;
					else multipath_time_delay_ns-=5;
					ad9959_change_multipath_phase(multipath_time_delay_ns, multipath_phase_delay_degree, mod_signal_freq_MHz, carrier_wave_freq_MHz);
					break;
				}
				case 5:{
					if(multipath_amp_attenuation_dB < 1) multipath_amp_attenuation_dB = 20;
					else multipath_amp_attenuation_dB-=2;
					set_pe43702_attenuation_dB(multipath_amp_attenuation_dB);
					break;
				}
				case 6:{
					if(multipath_phase_delay_degree < 1) multipath_phase_delay_degree = 360;
					multipath_phase_delay_degree-=5;
					ad9959_change_multipath_phase(multipath_time_delay_ns, multipath_phase_delay_degree, mod_signal_freq_MHz, carrier_wave_freq_MHz);
					break;
				}
				default: break;
			}
		}
		key2_pin_state_old = key2_pin_state_new;
		
		key1_pin_state_new = HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin);
		if ((key1_pin_state_new == GPIO_PIN_RESET) && (key1_pin_state_old == GPIO_PIN_SET)){
			HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_RESET);
			function++;
			if(function>6) function = 1;
		}
		key1_pin_state_old = key1_pin_state_new;
		
		key0_pin_state_new = HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin);
		if ((key0_pin_state_new == GPIO_PIN_RESET) && (key0_pin_state_old == GPIO_PIN_SET)){
			HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_RESET);
			switch(function){
				case 1:{
					carrier_wave_freq_MHz++;
					if(carrier_wave_freq_MHz > 40) carrier_wave_freq_MHz = 40;
					ad9959_change_carrier_wave_freq(carrier_wave_freq_MHz);
					ad603_change_carrier_wave_amp(carrier_wave_amp_effective_mV, carrier_wave_freq_MHz, Ma_percent);
					ad9959_change_multipath_phase(multipath_time_delay_ns, multipath_phase_delay_degree, mod_signal_freq_MHz, carrier_wave_freq_MHz);
					break;
				}
				case 2:{
					carrier_wave_amp_effective_mV+=100;
					if(carrier_wave_amp_effective_mV > 1000) carrier_wave_amp_effective_mV = 1000;
					ad603_change_carrier_wave_amp(carrier_wave_amp_effective_mV, carrier_wave_freq_MHz, Ma_percent);
					break;
				}
				case 3:{
					Ma_percent+=10;
					if(Ma_percent > 90) Ma_percent = 0;
					ad9959_change_mod_signal_amp(Ma_percent);
					ad603_change_carrier_wave_amp(carrier_wave_amp_effective_mV, carrier_wave_freq_MHz, Ma_percent);
					break;
				}
				case 4:{
					multipath_time_delay_ns+=10;
					if(multipath_time_delay_ns > 200) multipath_time_delay_ns = 0;
					ad9959_change_multipath_phase(multipath_time_delay_ns, multipath_phase_delay_degree, mod_signal_freq_MHz, carrier_wave_freq_MHz);
					break;
				}
				case 5:{
					multipath_amp_attenuation_dB+=2;
					if(multipath_amp_attenuation_dB > 20) multipath_amp_attenuation_dB = 0;
					set_pe43702_attenuation_dB(multipath_amp_attenuation_dB);
					break;
				}
				case 6:{
					multipath_phase_delay_degree+=15;
					if(multipath_phase_delay_degree >= 360) multipath_phase_delay_degree = 0;
					ad9959_change_multipath_phase(multipath_time_delay_ns, multipath_phase_delay_degree, mod_signal_freq_MHz, carrier_wave_freq_MHz);
					break;
				}
				default: break;
			}
		}
		key0_pin_state_old = key0_pin_state_new;
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_SET);
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 8;
  RCC_OscInitStruct.PLL.PLLN = 168;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
